var DateSelector = Class.create({
  FIRSTYEAR:2008,
  initialize:function(id,elem,callback,year,month,day,indicate)
  {
    this.id = id;
    this.elem = $(elem);
    this.callback = callback;
    this.indicate = indicate;
    var dateObj = null;
    if(year && month && day)
    {
      dateObj = new Date(year,month-1,day);
    }
    else
    {
      dateObj = new Date();
    }
    this.year = dateObj.getFullYear();
    this.month = dateObj.getMonth()+1;
    this.day = dateObj.getDate();
    this.setYearSelector();
    this.setMonthSelector();
    this.setDaySelector();
    if(this.indicate)
    {
      this.elem.insert({top:'<a href="#" id="beforeLink">&lt;前日</a>',
                      bottom:'<a href="#" id="nextLink">翌日&gt;</a>'});
      $('beforeLink').observe('click',this.changeBefore.bind(this));
      $('nextLink').observe('click',this.changeNext.bind(this));
    }
  },
  changeBefore:function(){
    this.setNewDate(-1);
  },
  changeNext:function(){
    this.setNewDate(1);
  },
  setNewDate:function(day){
    var nYear = parseInt($F(this.id+'_year'),10);
    var nMonth = parseInt($F(this.id+'_month'),10);
    var nDay = parseInt($F(this.id+'_day'),10)+day;
    if(!this.validate(nYear,nMonth,nDay))
    {
      if(nDay > 0)
      {
        nMonth+=1;
        nDay = 1;
        if(nMonth > 12)
        {
          nMonth = 1;
          nYear += 1;
        }
      }
      else
      {
        nMonth-=1;
        if(nMonth < 1)
        {
          nMonth = 12;
          nYear -= 1;
        }
        nDay = 31;
        while(!this.validate(nYear,nMonth,nDay)){
            nDay -=1;
        }
      }
    }
    var firstDate = new Date(this.FIRSTYEAR,0,1);
    var selectDate = new Date(nYear,nMonth-1,nDay);
    var nextYear = new Date().getFullYear()+1;
    var lastDate = new Date(nextYear,11,31);
    if(selectDate.getTime() < firstDate.getTime())
    {
      return;
    }
    if(selectDate.getTime() > lastDate.getTime())
    {
      return;
    }
    if(selectDate.getTime() == firstDate.getTime()){
      nYear = this.FIRSTYEAR;
      nMonth = 1;
      nDay = 1;
      $('beforeLink').addClassName("noLink");
    }
    else
    {
      $('beforeLink').removeClassName("noLink");
      if(selectDate.getTime() == lastDate.getTime()){
        nYear = nextYear;
        nMonth = 12;
        nDay = 31;
        $('nextLink').addClassName("noLink");
      }
      else
      {
        $('nextLink').removeClassName("noLink");
      }
    }
    this.year = nYear;
    this.month = nMonth;
    this.day = nDay;
    this.setYearSelector();
    this.setMonthSelector();
    this.setDaySelector();
  },
  changeDate:function(){
      $(this.id+'_day').stopObserving('change');
      var i=$F(this.id+'_day');
      while(!this.validate($F(this.id+'_year'),$F(this.id+'_month'),i))
      {
        i-=1;
      }
      this.day = i;
      this.setDaySelector();
   },
  dispDate:function(){
      this.setWeekDay();
      if(this.callback)
      {
        this.callback();
      }
  },
  setYearSelector:function(){
    if(!this.year_elem)
    {
      this.year_elem = new Element('span',{id:this.id+'_year_span'});
      this.elem.appendChild(this.year_elem);
    }
    else
    {
      $(this.id+'_year').stopObserving('change');
    }
    var year = this.year;
    var nowYear = new Date().getFullYear();
    var selectStr = '<select name="'+this.id+'_year" id="'+this.id+'_year">';
    for (var i=this.FIRSTYEAR ;i<=nowYear+1;i++)
    {
      var selected="";
      if(i == year)
      {
          selected = 'selected="selected"';
      }
      selectStr += '<option value="'+i+'" ' + selected +'>'+i+'</option>';
    }
    selectStr+='</select>年';
    $(this.year_elem).innerHTML=selectStr;
    $(this.id+'_year').observe('change',this.changeDate.bind(this));
  },
  setMonthSelector:function(ref){
    if(!this.month_elem)
    {
      this.month_elem = new Element('span',{id:this.id+'_month_span'});
      this.elem.appendChild(this.month_elem);
    }
    else
    {
      $(this.id+'_month').stopObserving('change');
    }
    var month = this.month;
    var selectStr = '<select name="'+this.id+'_month" id="'+this.id+'_month">';
    for (var i=1 ;i<=12;i++)
    {
      var selected="";
      if(i == month)
      {
          selected = 'selected="selected"';
      }
      selectStr += '<option value="'+i+'" ' + selected + '>'+i+'</option>';
    }
    selectStr+='</select>月';
    $(this.month_elem).innerHTML=selectStr;
    $(this.id+'_month').observe('change',this.changeDate.bind(this));
  },
  setDaySelector:function(ref){
    if(!this.day_elem)
    {
      this.day_elem = new Element('span',{id:this.id+'_day_span'});
      this.elem.appendChild(this.day_elem);
    }
    var day = this.day;
    selectStr = '<select name="'+this.id+'_day" id="'+this.id+'_day">';
    nYear = parseInt($F(this.id+'_year'));
    nMonth = parseInt($F(this.id+'_month'));
    for (var i=1 ;i<=31;i++)
    {
      if(!this.validate(nYear,nMonth,i))
      {
        break;
      }
      var selected="";
      if(i == day)
      {
        selected = 'selected="selected"';
      }
      selectStr += '<option value="'+i+'" ' + selected + '>'+i+'</option>';
    }
    selectStr+='</select>日';
    $(this.day_elem).innerHTML=selectStr;
    $(this.id+'_day').observe('change',this.dispDate.bind(this));
    this.setWeekDay();
    if(this.callback)
    {
      this.callback();
    }
  },
  getSelectDateObj:function()
  {
    year = $F(this.id+"_year");
    month = $F(this.id+"_month");
    day = $F(this.id+"_day");
    return new Date(year,month-1,day);
  },
  setWeekDay:function()
  {
    if(!this.weekday_elem)
    {
      this.weekday_elem = new Element('span',{id:this.id+'_weekday_span'});
      this.elem.appendChild(this.weekday_elem);
    }
    var dateObj = this.getSelectDateObj();
    var weekday= "";
    switch(dateObj.getDay())
    {
      case 0:
        weekday="(日)";
        break;
      case 1:
        weekday="(月)";
        break;
      case 2:
        weekday="(火)";
        break;
      case 3:
        weekday="(水)";
        break;
      case 4:
        weekday="(木)";
        break;
      case 5:
        weekday="(金)";
        break;
      case 6:
        weekday="(土)";
        break;
    }
    $(this.weekday_elem).innerHTML=weekday;
  },
  getDateStr:function()
  {
    return $F(this.id+'_year')+"年"+$F(this.id+'_month')+"月"+$F(this.id+'_day')+"日";
  },
  validate:function(year,month,day)
  {
    var tmp = new Date(year,month-1,day);
    return month == (tmp.getMonth() + 1)
  },
  validateDate:function()
  {
    return this.validate($F(this.id+'_year'),$F(this.id+'_month'),$F(this.id+'_day'));
  }
});
